﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using MiniStock.BusinessLogic.EventQueue.Data;

namespace MiniStock.BusinessLogic.EventQueue.Queue
{
    public class EventProcessorDbRepository: IEventProcessorRepository
    {
        #region IRepository<EventQueueEventListenerData> Members

        public bool BatchCommit { get; set; }

        protected EventDispatcherContext context = new EventDispatcherContext();

        public EventQueueEventProcessorData Add(EventQueueEventProcessorData item)
        {
            context.Listeners.Add(item);
            
            if(!BatchCommit) context.SaveChanges();
            return item;
        }

        public EventQueueEventProcessorData Update(EventQueueEventProcessorData item)
        {
            context.Listeners.Attach(item);
            if (!BatchCommit) context.SaveChanges();
            return item;
        }

        public void Delete(EventQueueEventProcessorData item)
        {
            context.Listeners.Remove(item);
            if(!BatchCommit) context.SaveChanges();
        }

        public void Commit()
        {
            context.SaveChanges();
        }

        public EventQueueEventProcessorData GetEventProcessorByEntityHash(string entityHash)
        {
            var hash = context.ClientAffinity.FirstOrDefault(i => i.EntityHash == entityHash);
            if (hash == null)
            {
                Trace.TraceWarning("Affinity record not found for entity hash: " + entityHash);
                return null;
            }

            var client = context.Listeners
                .OrderBy(i => i.NextFetchDate)
                .FirstOrDefault(i => i.ClientHash == hash.ClientHash);

            return client;
        }

        #endregion

        #region IEnumerable<EventQueueEventListenerData> Members

        public IEnumerator<EventQueueEventProcessorData> GetEnumerator()
        {
            return context.Listeners.AsEnumerable().GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return context.Listeners.AsEnumerable().GetEnumerator();
        }

        #endregion

        #region IQueryable Members

        public Type ElementType
        {
            get { return context.Listeners.AsQueryable().ElementType; }
        }

        public System.Linq.Expressions.Expression Expression
        {
            get { return context.Listeners.AsQueryable().Expression; }
        }

        public IQueryProvider Provider
        {
            get { return context.Listeners.AsQueryable().Provider; }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            context.Dispose();
        }

        #endregion

     }
}
